package com.zatech.cgnci.project.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zatech.cgnci.project.base.context.UserContext;
import com.zatech.cgnci.project.base.enums.BusinessStatusEnum;
import com.zatech.cgnci.project.base.enums.ResponseCodeEnum;
import com.zatech.cgnci.project.base.exception.GlobalException;
import com.zatech.cgnci.project.base.utils.ConvertUtils;
import com.zatech.cgnci.project.base.utils.DateUtils;
import com.zatech.cgnci.project.base.utils.VerifyUtils;
import com.zatech.cgnci.project.dto.*;
import com.zatech.cgnci.project.entity.*;
import com.zatech.cgnci.project.mapper.CgnciApprovalConfigMapper;
import com.zatech.cgnci.project.mapper.CgnciApprovalInfoMapper;
import com.zatech.cgnci.project.mapper.CgnciApprovalRecordMapper;
import com.zatech.cgnci.project.service.CgnciApprovalConfigRoleUserService;
import com.zatech.cgnci.project.service.IApprovalService;
import com.zatech.cgnci.project.vo.ApprovalConfigVO;
import com.zatech.cgnci.project.vo.ApprovalInfoVO;
import com.zatech.cgnci.project.vo.ApprovalProcessVO;
import com.zatech.cgnci.project.vo.FlowTaskVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author EDY
 * @version 1.0
 * Create by 2024/12/17 18:06
 */
@Slf4j
@Service
public class ApprovalServiceImpl implements IApprovalService {

    @Resource
    private CgnciApprovalInfoMapper approvalInfoMapper;
    @Resource
    private CgnciApprovalRecordMapper approvalRecordMapper;
    @Resource
    private CgnciApprovalConfigMapper approvalConfigMapper;
    @Resource
    CgnciApprovalConfigRoleUserService approvalConfigRoleUserService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApprovalInfoVO create(FlowTaskCreateDTO flowTaskCreateDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        // 必填参数校验
        if (VerifyUtils.isEmpty(flowTaskCreateDTO.getApprovalConfigGroupId()) || VerifyUtils.isEmpty(flowTaskCreateDTO.getFormId())
                || VerifyUtils.isEmpty(flowTaskCreateDTO.getFormNo())) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "参数校验失败");
        }

        // 校验同一个分组,同一个业务编号是否结束,否则抛出异常
        CgnciApprovalInfoDO approvalInfoDO = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormNo, flowTaskCreateDTO.getFormNo())
                .eq(CgnciApprovalInfoDO::getApprovalConfigGroupId, flowTaskCreateDTO.getApprovalConfigGroupId())
                .eq(CgnciApprovalInfoDO::getIsEnd, 0));
        if (VerifyUtils.isNotEmpty(approvalInfoDO)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "已有在途任务号:" + approvalInfoDO.getTaskId() + "，不可新增任务");
        }

        // 查找流程分组第一个节点
        CgnciApprovalConfigDO zeroConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, flowTaskCreateDTO.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, 0));
        if (VerifyUtils.isEmpty(zeroConfig)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程当前结点未配置");
        }

        // 判断当前用户是否可以创建任务
        boolean isCreate = checkIfCreate(zeroConfig, user.getUsercode());
        if (!isCreate) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前用户没有权限创建任务");
        }

        // 创建任务流程
        CgnciApprovalInfoDO approvalInfo = ConvertUtils.convert(flowTaskCreateDTO, CgnciApprovalInfoDO.class);
        approvalInfo.setTaskId("T" + System.currentTimeMillis());
        approvalInfo.setApprovalConfigGroupType(zeroConfig.getGroupType());
        approvalInfo.setFounderId(user.getUsercode());
        approvalInfo.setFounderName(user.getUsername());
        approvalInfo.setLaunchTime(new Date());
        approvalInfo.setApprovalNode(zeroConfig.getApprovalNode());
        approvalInfo.setTaskType(zeroConfig.getTaskType());
        approvalInfo.setTaskTypeCode(zeroConfig.getTaskTypeCode());
        approvalInfo.setProcessName(zeroConfig.getProcessName());
        approvalInfo.setCurrentApproverNode(zeroConfig.getCurrentApproverNode());
        List<CgnciApprovalConfigRoleUserDO> list = approvalConfigRoleUserService.listCreateUser(zeroConfig.getTaskType(), zeroConfig.getCurrentApproverNode(), user.getUsercode());
        if (VerifyUtils.isNotEmpty(list)) {
            // 添加代理人，目的是为了工作台中代理人也可以查到当前任务
            approvalInfo.setCurrentAgentAndName(list.stream().map(value -> value.getCurrentApproverName() + "-" + value.getCurrentApprover()).collect(Collectors.joining(",")));
            // 把当前节点的处理人也加入到当前处理人的代理人列表中
            // list.add(CgnciApprovalConfigRoleUserDO.builder().currentApproverName(user.getUsername()).currentApprover(user.getUsercode()).build());
            // approvalInfo.setCurrentApproverAndName(list.stream().map(value -> value.getCurrentApproverName() + "-" + value.getCurrentApprover()).collect(Collectors.joining(",")));
        } else {
            // approvalInfo.setCurrentApproverAndName(user.getNameAndCode());
        }

        approvalInfo.setCurrentApproverAndName(user.getNameAndCode());
        approvalInfo.setStatus(BusinessStatusEnum.ENTERING.getCode());
        approvalInfoMapper.insert(approvalInfo);
        return ConvertUtils.convert(approvalInfo, ApprovalInfoVO.class);
    }

    /**
     * 提交审核、退回再次提交审核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FlowTaskVO submit(FlowTaskSubmitDTO flowTaskSubmitDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        log.info("approvalServiceImpl#submit request:{}", JSON.toJSONString(flowTaskSubmitDTO));
        // 校验任务流程
        CgnciApprovalInfoDO approvalInfo = approvalInfoMapper.selectById(flowTaskSubmitDTO.getApprovalInfoId());
        if (VerifyUtils.isEmpty(approvalInfo) && VerifyUtils.isNotEmpty(flowTaskSubmitDTO.getFormId())) {
            approvalInfo = approvalInfoByFormId(flowTaskSubmitDTO);
        }
        if (VerifyUtils.isEmpty(approvalInfo)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程不存在");
        }

        // 获取当前节点的配置
        CgnciApprovalConfigDO currentApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode()));
        if (VerifyUtils.isEmpty(currentApprovalConfig)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程当前节点未配置");
        }

        // 获取下一个节点的配置
        CgnciApprovalConfigDO nextApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode() + 1));
        if (VerifyUtils.isEmpty(nextApprovalConfig)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程提交审核节点未配置");
        }

        // 校验是否有权限提交审批,只有发起人才可以提交提交审批
        Map<String, Object> taskApprovalInfo = this.getTaskApprovalInfo(approvalInfo, currentApprovalConfig, user.getUsercode());
        if ((Boolean) taskApprovalInfo.get("isTaskEnded") || !(Boolean) taskApprovalInfo.get("isInitiator")) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前用户不能提交审核");
        }

        // 维护一个流程状态
        approvalInfo.setStatus(nextApprovalConfig.getForwardStatus());

        // 重置流程开始
        approvalInfo.setIsEnd(0);
        approvalInfo.setEndTime(null);
        // 下一个节点
        approvalInfo.setApprovalNode(nextApprovalConfig.getApprovalNode());
        // 上一个节点处理人
        approvalInfo.setPreviousApproverNode(approvalInfo.getCurrentApproverNode());
        approvalInfo.setPreviousApproverAndName(user.getNameAndCode());
        // 当前节点处理人
        approvalInfo.setCurrentApproverNode(nextApprovalConfig.getCurrentApproverNode());
        // 根据任务类型和审批角色查询审批人
        List<CgnciApprovalConfigRoleUserDO> list = approvalConfigRoleUserService.listApprovalUser(nextApprovalConfig.getTaskType(), nextApprovalConfig.getCurrentApproverNode());
        if (VerifyUtils.isEmpty(list)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程:{" + approvalInfo.getTaskType() + "}" + nextApprovalConfig.getCurrentApproverNode() + "的节点未配置审批人");
        }
        approvalInfo.setCurrentApproverAndName(list.stream().map(value -> value.getCurrentApproverName() + "-" + value.getCurrentApprover()).collect(Collectors.joining(",")));
        approvalInfoMapper.updateById(approvalInfo);

        // 创建当前任务记录
        CgnciApprovalRecordDO currentRecord = approvalRecordMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalRecordDO>()
                .eq(CgnciApprovalRecordDO::getApprovalInfoId, approvalInfo.getApprovalInfoId())
                .orderByDesc(CgnciApprovalRecordDO::getCreateTime)
                .last("limit 1"));
        if (VerifyUtils.isNotEmpty(currentRecord)) {
            currentRecord.setApproverTime(new Date());
            currentRecord.setApproverOpinions("提交审核");
            approvalRecordMapper.updateById(currentRecord);
        } else {
            currentRecord = new CgnciApprovalRecordDO();
            currentRecord.setApprovalInfoId(approvalInfo.getApprovalInfoId());
            currentRecord.setFormId(approvalInfo.getFormId());
            currentRecord.setApproverTime(new Date());
            currentRecord.setApproverOpinions("提交审核");
            currentRecord.setApprovalNode(currentApprovalConfig.getApprovalNode());
            currentRecord.setCurrentApproverNode(approvalInfo.getPreviousApproverNode());
            currentRecord.setCurrentApproverAndName(approvalInfo.getPreviousApproverAndName());
            approvalRecordMapper.insert(currentRecord);
        }

        // 创建下一个任务记录
        CgnciApprovalRecordDO nextRecord = createApprovalRecord(approvalInfo);
        approvalRecordMapper.insert(nextRecord);
        // 返回当前流程结束之后的状态给业务方
        FlowTaskVO flowTaskVO = FlowTaskVO.builder().status(nextApprovalConfig.getForwardStatus()).statusDesc(nextApprovalConfig.getForwardStatusDesc()).isEnd(approvalInfo.getIsEnd()).build();
        log.info("提交审核返回结果:{}", flowTaskVO);
        return flowTaskVO;

    }


    /**
     * 审批通过
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FlowTaskVO approve(FlowTaskApprovalDTO flowTaskApprovalDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        // 查询审批流程表
        CgnciApprovalInfoDO approvalInfo = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, flowTaskApprovalDTO.getFormId())
                .eq(CgnciApprovalInfoDO::getFormNo, flowTaskApprovalDTO.getFormNo()));
        if (VerifyUtils.isEmpty(approvalInfo)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程不存在");
        }

        // 获取当前节点的配置
        CgnciApprovalConfigDO currentApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode()));
        if (VerifyUtils.isEmpty(currentApprovalConfig)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程当前节点未配置");
        }

        // 获取下一个节点的配置
        CgnciApprovalConfigDO nextApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode() + 1));

        // 校验是否有权限审批
        Map<String, Object> taskApprovalInfo = this.getTaskApprovalInfo(approvalInfo, currentApprovalConfig, user.getUsercode());
        if ((Boolean) taskApprovalInfo.get("isTaskEnded") || !(Boolean) taskApprovalInfo.get("isApprover")) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前用户不能审批通过");
        }

        // 查询最新一条审批记录
        CgnciApprovalRecordDO currentRecord = approvalRecordMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalRecordDO>()
                .eq(CgnciApprovalRecordDO::getApprovalInfoId, approvalInfo.getApprovalInfoId())
                .orderByDesc(CgnciApprovalRecordDO::getCreateTime)
                .last("limit 1"));

        // 2. 更新当前审批记录
        currentRecord.setApproverTime(new Date());
        currentRecord.setApproverOpinions(flowTaskApprovalDTO.getApproverOpinions());
        approvalRecordMapper.updateById(currentRecord);

        FlowTaskVO flowTaskVO = FlowTaskVO.builder().build();
        approvalInfo.setPreviousApproverNode(approvalInfo.getCurrentApproverNode());
        approvalInfo.setPreviousApproverAndName(user.getNameAndCode());
        // 6. 如果存在下一节点，则创建下一节点的审批记录
        if (VerifyUtils.isNotEmpty(nextApprovalConfig)) {
            // 更新审批信息进度
            approvalInfo.setApprovalNode(nextApprovalConfig.getApprovalNode());
            approvalInfo.setCurrentApproverNode(nextApprovalConfig.getCurrentApproverNode());
            // 根据任务类型和审批角色查询审批人
            List<CgnciApprovalConfigRoleUserDO> list = approvalConfigRoleUserService.listApprovalUser(nextApprovalConfig.getTaskType(), nextApprovalConfig.getCurrentApproverNode());
            if (VerifyUtils.isEmpty(list)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程:{" + approvalInfo.getTaskType() + "}" + nextApprovalConfig.getCurrentApproverNode() + "的节点未配置审批人");
            }
            approvalInfo.setCurrentApproverAndName(list.stream().map(value -> value.getCurrentApproverName() + "-" + value.getCurrentApprover()).collect(Collectors.joining(",")));
            CgnciApprovalRecordDO nextRecord = createApprovalRecord(approvalInfo);
            approvalRecordMapper.insert(nextRecord);
            flowTaskVO.setStatus(nextApprovalConfig.getForwardStatus());
            flowTaskVO.setStatusDesc(nextApprovalConfig.getForwardStatusDesc());

            // 维护一个流程状态
            approvalInfo.setStatus(nextApprovalConfig.getForwardStatus());
        } else {
            // 任务完成
            approvalInfo.setIsEnd(1);
            approvalInfo.setEndTime(new Date());
            approvalInfo.setCurrentApproverNode(null);
            approvalInfo.setCurrentApproverAndName(null);
            flowTaskVO.setStatus(currentApprovalConfig.getEndStatus());
            flowTaskVO.setStatusDesc(currentApprovalConfig.getEndStatusDesc());

            // 维护一个流程状态
            approvalInfo.setStatus(currentApprovalConfig.getEndStatus());
        }
        approvalInfo.setStatus(BusinessStatusEnum.getEnumByCode(flowTaskVO.getStatus()).getCode());
        approvalInfoMapper.updateById(approvalInfo);
        flowTaskVO.setIsEnd(approvalInfo.getIsEnd());
        flowTaskVO.setFormNo(approvalInfo.getFormNo());
        log.info("审核返回结果:{}", flowTaskVO);
        return flowTaskVO;
    }

    /**
     * 退回任务到指定节点
     *
     * @param flowTaskBackDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FlowTaskVO back(FlowTaskBackDTO flowTaskBackDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        // 查询审批流程表
        CgnciApprovalInfoDO approvalInfo = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, flowTaskBackDTO.getFormId())
                .eq(CgnciApprovalInfoDO::getFormNo, flowTaskBackDTO.getFormNo()));
        if (VerifyUtils.isEmpty(approvalInfo)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程不存在");
        }

        // 获取当前节点的配置
        CgnciApprovalConfigDO currentApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode()));

        // 获取指定退回节点的配置
        CgnciApprovalConfigDO backApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, flowTaskBackDTO.getApprovalNode()));
        if (VerifyUtils.isEmpty(backApprovalConfig)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程退回节点未配置");
        }

        // 校验是否有权限审批
        Map<String, Object> taskApprovalInfo = this.getTaskApprovalInfo(approvalInfo, currentApprovalConfig, user.getUsercode());
        if ((Boolean) taskApprovalInfo.get("isTaskEnded") || !(Boolean) taskApprovalInfo.get("isApprover")) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前用户不能审批退回");
        }

        // 查询最新一条审批记录
        CgnciApprovalRecordDO currentRecord = approvalRecordMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalRecordDO>()
                .eq(CgnciApprovalRecordDO::getApprovalInfoId, approvalInfo.getApprovalInfoId())
                .orderByDesc(CgnciApprovalRecordDO::getCreateTime)
                .last("limit 1"));

        // 2. 更新当前审批记录
        currentRecord.setApproverTime(new Date());
        currentRecord.setApproverOpinions(flowTaskBackDTO.getApproverOpinions());
        approvalRecordMapper.updateById(currentRecord);

        // 更新审批信息进度
        approvalInfo.setApprovalNode(backApprovalConfig.getApprovalNode());
        approvalInfo.setPreviousApproverNode(approvalInfo.getCurrentApproverNode());
        approvalInfo.setPreviousApproverAndName(user.getNameAndCode());
        approvalInfo.setCurrentApproverNode(backApprovalConfig.getCurrentApproverNode());
        // 如果退回到发起人结点,处理人就是发起人姓名-工号和代理人姓名-工号
        if (0 == flowTaskBackDTO.getApprovalNode()) {
            /*List<CgnciApprovalConfigRoleUserDO> list = approvalConfigRoleUserService.listCreateUser(backApprovalConfig.getTaskType(), backApprovalConfig.getCurrentApproverNode(), approvalInfo.getFounderId());
            if (VerifyUtils.isNotEmpty(list)) {
                list.add(CgnciApprovalConfigRoleUserDO.builder().currentApproverName(approvalInfo.getFounderName()).currentApprover(approvalInfo.getFounderId()).build());
                approvalInfo.setCurrentApproverAndName(list.stream().map(value -> value.getCurrentApproverName() + "-" + value.getCurrentApprover()).collect(Collectors.joining(",")));
            } else {
                approvalInfo.setCurrentApproverAndName(approvalInfo.getFounderName() + "-" + approvalInfo.getFounderId());
            }*/
            approvalInfo.setCurrentApproverAndName(approvalInfo.getFounderName() + "-" + approvalInfo.getFounderId());
        } else {
            List<CgnciApprovalConfigRoleUserDO> list = approvalConfigRoleUserService.listApprovalUser(backApprovalConfig.getTaskType(), backApprovalConfig.getCurrentApproverNode());
            if (VerifyUtils.isEmpty(list)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程:{" + approvalInfo.getTaskType() + "}" + backApprovalConfig.getCurrentApproverNode() + "的节点未配置审批人");
            }
            approvalInfo.setCurrentApproverAndName(list.stream().map(value -> value.getCurrentApproverName() + "-" + value.getCurrentApprover()).collect(Collectors.joining(",")));
        }
        // 维护一个流程状态
        approvalInfo.setStatus(BusinessStatusEnum.getEnumByCode(backApprovalConfig.getBackStatus()).getCode());
        approvalInfoMapper.updateById(approvalInfo);
        CgnciApprovalRecordDO nextRecord = createApprovalRecord(approvalInfo);
        approvalRecordMapper.insert(nextRecord);
        FlowTaskVO flowTaskVO = FlowTaskVO.builder().status(backApprovalConfig.getBackStatus()).statusDesc(backApprovalConfig.getBackStatusDesc()).isEnd(approvalInfo.getIsEnd()).build();
        log.info("审核返回结果:{}", flowTaskVO);
        return flowTaskVO;
    }

    /**
     * 创建审批记录
     */
    private CgnciApprovalRecordDO createApprovalRecord(CgnciApprovalInfoDO approvalInfo) {
        CgnciApprovalRecordDO record = new CgnciApprovalRecordDO();
        record.setApprovalInfoId(approvalInfo.getApprovalInfoId());
        record.setFormId(approvalInfo.getFormId());
        record.setApprovalNode(approvalInfo.getApprovalNode());
        record.setCurrentApproverNode(approvalInfo.getCurrentApproverNode());
        record.setCurrentApproverAndName(approvalInfo.getCurrentApproverAndName());
        record.setPreviousApproverNode(approvalInfo.getPreviousApproverNode());
        record.setPreviousApproverAndName(approvalInfo.getPreviousApproverAndName());
        return record;
    }

    /**
     * 获取代办任务
     *
     * @param approverUserId 当前用户ID
     * @return 待办任务列表（包括任务状态和权限）
     */
    @Override
    public List<Map<String, Object>> getTodoTasks(String approverUserId) {
        // 1. 查询待办任务列表
        List<ApprovalInfoVO> todoTasks = approvalInfoMapper.selectTodoTasksByUserId(approverUserId);

        // 2. 对每个任务进行权限判断
        List<Map<String, Object>> result = new ArrayList<>();
        for (ApprovalInfoVO approvalInfo : todoTasks) {
            // 获取当前节点的配置
            CgnciApprovalConfigDO currentApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                    .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                    .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode()));
            if (VerifyUtils.isEmpty(currentApprovalConfig)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程当前节点未配置");
            }
            Map<String, Object> taskInfo = this.getTaskApprovalInfo(approvalInfo, currentApprovalConfig, approverUserId);
            // 将任务信息放入结果中
            taskInfo.put("task", approvalInfo);
            result.add(taskInfo);
        }
        return result;
    }

    /**
     * 获取已办任务
     *
     * @param approverUserId 当前用户ID
     * @return 已办任务列表（包括任务状态和权限）
     */
    @Override
    public List<Map<String, Object>> getDoneTasks(String approverUserId) {
        // 1. 查询已办任务列表
        List<ApprovalInfoVO> doneTasks = approvalInfoMapper.selectDoneTasksByUserId(approverUserId);

        // 2. 对每个任务进行权限判断
        List<Map<String, Object>> result = new ArrayList<>();
        for (ApprovalInfoVO approvalInfo : doneTasks) {
            // 获取当前节点的配置
            CgnciApprovalConfigDO currentApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                    .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                    .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode()));
            if (VerifyUtils.isEmpty(currentApprovalConfig)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程当前节点未配置");
            }
            Map<String, Object> taskInfo = this.getTaskApprovalInfo(approvalInfo, currentApprovalConfig, approverUserId);
            taskInfo.put("task", approvalInfo); // 将任务信息放入结果中
            result.add(taskInfo);
        }
        return result;
    }

    /**
     * 获取当前任务的审批信息和权限判断
     *
     * @param approvalInfo
     * @param currentApprovalConfig
     * @param currentUserId
     * @return 当前任务的相关信息和权限
     */
    @Override
    public Map<String, Object> getTaskApprovalInfo(CgnciApprovalInfoDO approvalInfo, CgnciApprovalConfigDO currentApprovalConfig, String currentUserId) {

        // 判断是否为发起人或者是否为代理人，有编辑、取消等操作权限
        boolean isInitiator = checkIfInitiator(currentApprovalConfig, currentUserId, approvalInfo.getFounderId());

        // 判断当前用户是否是该节点的审批人
        boolean isApprover = checkIfApprover(currentApprovalConfig, currentUserId);

        // 判断当前任务的状态（例如是否已经结束）
        boolean isTaskEnded = 1 == approvalInfo.getIsEnd();

        // 判断任务是否有权限取消（发起人有权限取消）
        boolean canCancelTask = isInitiator && !isTaskEnded;

        // 生成返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("isInitiator", isInitiator); // 当前用户是否是发起人
        result.put("isApprover", isApprover); // 当前用户是否是审批人
        result.put("canCancelTask", canCancelTask); // 发起人是否能取消任务
        result.put("isTaskEnded", isTaskEnded); // 任务是否已结束
        log.info("获取当前任务的审批信息和权限判断的返回结果:{}", result);
        return result;
    }


    @Override
    public List<ApprovalConfigVO> listBackNode(String formId, String formNo) {
        CgnciApprovalInfoDO approvalInfo = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, formId)
                .eq(CgnciApprovalInfoDO::getFormNo, formNo));
        if (VerifyUtils.isEmpty(approvalInfo)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务不存在");
        }
        // 获取指定分组,小于某节点的所有节点
        List<CgnciApprovalConfigDO> CgnciApprovalConfigDOList = approvalConfigMapper.selectList(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .lt(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode())
                .orderByDesc(CgnciApprovalConfigDO::getApprovalNode));
        return ConvertUtils.convert(CgnciApprovalConfigDOList, ApprovalConfigVO.class);
    }


    private boolean checkIfCreate(CgnciApprovalConfigDO currentApprovalConfig, String approverUserId) {
        // 判断当前用户是否可以创建任务，排除代理人
        List<CgnciApprovalConfigRoleUserDO> roleUserDOS = approvalConfigRoleUserService.list(new LambdaQueryWrapper<CgnciApprovalConfigRoleUserDO>()
                .eq(CgnciApprovalConfigRoleUserDO::getTaskType, currentApprovalConfig.getTaskType())
                .isNull(CgnciApprovalConfigRoleUserDO::getAuthCode)
                .isNull(CgnciApprovalConfigRoleUserDO::getAuthName)
                .eq(CgnciApprovalConfigRoleUserDO::getCurrentApproverNode, "发起人")
                .eq(CgnciApprovalConfigRoleUserDO::getCurrentApprover, approverUserId));
        return VerifyUtils.isNotEmpty(roleUserDOS);
    }

    private boolean checkIfInitiator(CgnciApprovalConfigDO currentApprovalConfig, String currentUserId, String founderId) {
        // 判断当前用户是否是发起人
        boolean isEquals = currentUserId.equals(founderId);

        // 判断当前用户是否是发起人的代理人
        CgnciApprovalConfigRoleUserDO roleUserDO = approvalConfigRoleUserService.getOne(new LambdaQueryWrapper<CgnciApprovalConfigRoleUserDO>()
                .eq(CgnciApprovalConfigRoleUserDO::getTaskType, currentApprovalConfig.getTaskType())
                .eq(CgnciApprovalConfigRoleUserDO::getAuthCode, founderId)
                .eq(CgnciApprovalConfigRoleUserDO::getCurrentApprover, currentUserId)
                .le(CgnciApprovalConfigRoleUserDO::getStartDate, DateUtils.dateToString(new Date(),DateUtils.FORMAT_3))// start_date <= target_date
                .ge(CgnciApprovalConfigRoleUserDO::getEndDate, DateUtils.dateToString(new Date(),DateUtils.FORMAT_3)));// end_date >= target_date);

        // 两个有一个满足返回true
        return isEquals || VerifyUtils.isNotEmpty(roleUserDO);
    }

    /**
     * 判断当前用户是否是该节点的审批人
     *
     * @param currentApprovalConfig
     * @param currentUserId
     * @return 是否为审批人
     */
    private boolean checkIfApprover(CgnciApprovalConfigDO currentApprovalConfig, String currentUserId) {
        // 根据任务类型和审批角色查询审批人
        List<CgnciApprovalConfigRoleUserDO> list = approvalConfigRoleUserService.list(new LambdaQueryWrapper<CgnciApprovalConfigRoleUserDO>()
                .eq(CgnciApprovalConfigRoleUserDO::getTaskType, currentApprovalConfig.getTaskType())
                .eq(CgnciApprovalConfigRoleUserDO::getCurrentApproverNode, currentApprovalConfig.getCurrentApproverNode()));
        if (VerifyUtils.isEmpty(list)) {
            return false;
        }
        CgnciApprovalConfigRoleUserDO isExist = list.stream().filter(value -> currentUserId.equals(value.getCurrentApprover())).findFirst().orElse(null);
        return VerifyUtils.isNotEmpty(isExist);
    }


    /**
     * 取消任务（只有发起人有权限）
     *
     * @param flowTaskCancelDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelTask(FlowTaskCancelDTO flowTaskCancelDTO) {
        // 获取当前登录用户
        UserEntity user = UserContext.getUser();
        if (VerifyUtils.isEmpty(flowTaskCancelDTO.getFormId()) || VerifyUtils.isEmpty(flowTaskCancelDTO.getFormNo())) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "参数错误");
        }
        // 获取审批信息
        CgnciApprovalInfoDO approvalInfo = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, flowTaskCancelDTO.getFormId())
                .eq(CgnciApprovalInfoDO::getFormNo, flowTaskCancelDTO.getFormNo()));
        if (VerifyUtils.isEmpty(approvalInfo)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务不存在");
        }

        // 获取当前节点的配置
        CgnciApprovalConfigDO currentApprovalConfig = approvalConfigMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                .eq(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode()));
        if (VerifyUtils.isEmpty(currentApprovalConfig)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务流程当前节点未配置");
        }

        // 校验是否有权限注销
        Map<String, Object> taskApprovalInfo = this.getTaskApprovalInfo(approvalInfo, currentApprovalConfig, user.getUsercode());
        if (!(Boolean) taskApprovalInfo.get("canCancelTask")) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "当前用户不能注销或取消任务");
        }

        // 查询最新一条审批记录
        CgnciApprovalRecordDO currentRecord = approvalRecordMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalRecordDO>()
                .eq(CgnciApprovalRecordDO::getApprovalInfoId, approvalInfo.getApprovalInfoId())
                .orderByDesc(CgnciApprovalRecordDO::getCreateTime)
                .last("limit 1"));

        if (VerifyUtils.isNotEmpty(currentRecord)) {
            currentRecord.setApprovalNode(-1);
            currentRecord.setApproverTime(new Date());
            currentRecord.setApproverOpinions("注销");
            approvalRecordMapper.updateById(currentRecord);
        } else {
            currentRecord = new CgnciApprovalRecordDO();
            currentRecord.setApprovalInfoId(approvalInfo.getApprovalInfoId());
            currentRecord.setFormId(approvalInfo.getFormId());
            //currentRecord.setApproverUserId(approvalInfo.getCurrentApprover());
            currentRecord.setApproverTime(new Date());
            currentRecord.setApproverOpinions("注销");
            currentRecord.setApprovalNode(-1);
            currentRecord.setPreviousApproverNode(approvalInfo.getCurrentApproverNode());
            //currentRecord.setPreviousApproverName(approvalInfo.getCurrentApproverName());
            //currentRecord.setPreviousApprover(approvalInfo.getCurrentApprover());
            currentRecord.setPreviousApproverAndName(approvalInfo.getCurrentApproverAndName());
            currentRecord.setCurrentApproverNode(null);
            //currentRecord.setCurrentApprover(null);
            //currentRecord.setCurrentApproverName(null);
            currentRecord.setCurrentApproverAndName(null);
            approvalRecordMapper.insert(currentRecord);
        }

        approvalInfo.setApprovalNode(-1);
        approvalInfo.setIsEnd(1);
        approvalInfo.setEndTime(new Date());
        approvalInfo.setPreviousApproverNode(approvalInfo.getCurrentApproverNode());
        //approvalInfo.setPreviousApproverName(approvalInfo.getCurrentApproverName());
        //approvalInfo.setPreviousApprover(approvalInfo.getCurrentApprover());
        approvalInfo.setPreviousApproverAndName(user.getNameAndCode());
        approvalInfo.setCurrentApproverNode(null);
        //approvalInfo.setCurrentApprover(null);
        //approvalInfo.setCurrentApproverName(null);
        approvalInfo.setCurrentApproverAndName(null);
        approvalInfo.setStatus(BusinessStatusEnum.SIGN_OUT.getCode());
        approvalInfoMapper.updateById(approvalInfo);

    }

    /**
     * 获取当前流程节点记录
     *
     * @param approvalInfoId 审批信息ID
     * @return 流程节点记录列表
     */
    public List<CgnciApprovalRecordDO> getCurrentFlowRecords(Long approvalInfoId) {
        return approvalRecordMapper.selectRecordsByApprovalInfoId(approvalInfoId);
    }


    /**
     * 获取任务的审批流程，构建树形结构
     *
     * @param approvalInfoId 审批信息ID
     * @return 审批流程信息
     */
    @Override
    public List<ApprovalProcessVO> getApprovalProcess(String groupId, Long approvalInfoId) {
        // 查询审批记录并按节点顺序排序
        List<CgnciApprovalRecordDO> approvalRecords = approvalRecordMapper.selectRecordsByApprovalInfoId(approvalInfoId);

        List<ApprovalProcessVO> approvalProcessList = new ArrayList<>();

        // 遍历审批记录，构建树形结构
        for (CgnciApprovalRecordDO record : approvalRecords) {
            ApprovalProcessVO dto = new ApprovalProcessVO();
            // 使用动态获取的节点名称
            dto.setNode(getNodeName(groupId, record.getApprovalNode()));
            dto.setApprover(record.getCurrentApproverAndName());
            dto.setTime(record.getApproverTime() == null ? "" : record.getApproverTime().toString());
            // 使用动态获取的审批状态
            // dto.setStatus(getApprovalStatus(record.getApproverResult() == null ? 0 : record.getApproverResult()));
            dto.setOpinion(record.getApproverOpinions());

            // 退回的节点
            /*if (record.getApproverResult() != null) {
                // 退回
                if (record.getApproverResult() == 2) {
                    // 获取上一节点
                    dto.setReturnTo(getNodeName(groupId, record.getApproverNode() - 1));
                }
            }*/
            approvalProcessList.add(dto);
        }

        return approvalProcessList;
    }

    public String getNodeName(String groupId, Integer node) {
        CgnciApprovalConfigDO config = approvalConfigMapper.selectByGroupIdAndNode(groupId, node);
        if (config != null) {
            return config.getCurrentApproverNode();
        } else {
            return "未知";
        }
    }

    private CgnciApprovalInfoDO approvalInfoByFormId(FlowTaskSubmitDTO flowTaskApprovalDTO) {
        if (Objects.isNull(flowTaskApprovalDTO)) {
            return null;
        }
        return approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, flowTaskApprovalDTO.getFormId())
                .eq(CgnciApprovalInfoDO::getIsEnd, 0));
    }

}

